/**
 * @file singleton.h
 * @author  haifeng (haifengxiao@icloud.com)
 * @brief
 * @version 0.1
 * @date 2021-07-06
 *
 * @copyright Copyright (c) 2021
 *
 */
#pragma once

#include <memory>

namespace Chen {
    namespace {

        /**
         * @brief Get the Instance X object
         *
         * @tparam T
         * @tparam
         * @tparam N
         * @return T&
         */
        template<typename T, typename X, int N>
        T& GetInstanceX() {
            static T v;
            return v;
        }

        /**
         * @brief Get the Instance Ptr object
         *
         * @tparam T
         * @tparam
         * @tparam N
         * @return std::shared_ptr<T>
         */
        template<typename T, typename X, int N>
        std::shared_ptr<T> GetInstancePtr() {
            static std::shared_ptr<T> v(new T);
            return v;
        }

    }

    /**
     * @brief
     *
     * @tparam T
     * @tparam
     * @tparam N
     */
    template<class T, class X = void, int N = 0>
    class Singleton {
    public:
        /**
         * @brief Get the Instance object
         *
         * @return T* 返回单例裸指针
         */
        static T* GetInstance() {
            static T v;
            return &v;
        }
    };

    /**
     * @brief
     *
     * @tparam T
     * @tparam
     * @tparam N
     */
    template<class T, class X = void, int N = 0>
    class SingletonPtr {
    public:
        std::shared_ptr<T> GetInstancePtr() {
            static std::shared_ptr<T> v(new T);
            return v;
        }
    };

}//namespace Chen
